package com.open.basic;


import com.open.basic.constant.BizConstant;

import java.io.Serial;
import java.io.Serializable;
import java.util.List;


/**
 * @param <T> 结果集的数据类型
 * @author: system
 * @Date: 2024/4/11 23:44
 * @Version: V1.0
 * @description: desc:
 * 分页返回对象.<br>
 * 提供给外部系统的分页Bean<br>
 */
public class PageResponse<T> extends BaseResponse<T> implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 请求查询的页码
     */
    private int pageNo = 1;

    /**
     * 每页显示条数
     */
    private int pageSize = 10;

    /**
     * 结果集
     */
    private List<T> pageData;

    /**
     * 总条数
     */
    private long count = 0;

    /**
     * 总页数
     */
    private long pageCount;

    /**
     * 起始行
     */
    private long startRow;
    /**
     * 结束行
     */
    private long endRow;

    public PageResponse() {

    }

    public PageResponse(BizConstant bizConstant) {
        super(bizConstant);
    }

    /**
     * 构造函数
     *
     * @param success 是否成功
     * @param code    是否成功代码
     * @param message 是否成功信息
     */
    public PageResponse(boolean success, BizConstant code, String message) {
        super(success, code, message);
    }

    /**
     * 构造函数
     *
     * @param success  是否成功
     * @param code     是否成功代码
     * @param message  是否成功信息
     * @param causedBy 扩展信息 ，异常时存异常储堆栈信息
     */
    public PageResponse(boolean success, BizConstant code, String message, String causedBy) {
        super(success, code, message, causedBy);

    }

    /**
     * 构造函数
     *
     * @param success  是否成功
     * @param code     是否成功代码
     * @param message  是否成功信息
     * @param causedBy 扩展信息 ，异常时存异常储堆栈信息
     * @param data     业务执行结果
     */
    public PageResponse(boolean success, BizConstant code, String message, String causedBy, T data) {
        super(success, code, message, causedBy, data);

    }

    public static <T> PageResponse<T> success() {
        return new PageResponse<>(BizConstant.BIZ_SUCCESS);
    }

    public PageResponse<T> successful() {
        return success();
    }


    /**
     * 构造函数
     * result 业务执行结果
     */
    public static <T> PageResponse<T> success(T result) {
        PageResponse<T> response = new PageResponse<>(BizConstant.BIZ_SUCCESS);
        response.setData(result);
        return response;
    }

    public <T> PageResponse<T> successful(T result) {
        return success(result);
    }

    public PageResponse<T> successful(T result, long totalCount, Page page) {
        return success(totalCount, result, page);
    }

    public PageResponse<T> successful(T result, long totalCount, int pageNum, int pageSize) {
        return success(totalCount, result, pageNum, pageSize);
    }


    public static <T> PageResponse<T> success(long totalCount, T result, Page page) {
        PageResponse<T> response = new PageResponse<>(BizConstant.BIZ_SUCCESS);
        response.setData(result);
        response.setCount(totalCount);
        response.setPageNo(page.getPageNo());
        response.setPageSize(page.getPageSize());
        return response;
    }

    public static <T> PageResponse<T> success(long totalCount, T result, int pageNo, int pageSize) {
        PageResponse<T> response = new PageResponse<>(BizConstant.BIZ_SUCCESS);
        response.setData(result);
        response.setCount(totalCount);
        response.setPageNo(pageNo);
        response.setPageSize(pageSize);
        return response;
    }

    public PageResponse<T> successful(long totalCount, T result, long pageNum, long pageSize) {
        return success(totalCount, result, pageNum, pageSize);
    }

    public static <T> PageResponse<T> success(long totalCount, T result, long pageNum, long pageSize) {
        PageResponse<T> response = new PageResponse<>(BizConstant.BIZ_SUCCESS);
        response.setData(result);
        response.setCount(totalCount);
        response.setPageNo(Math.toIntExact(pageNum));
        response.setPageSize(Math.toIntExact(pageSize));
        return response;
    }

    /**
     * 构造函数
     *
     * @param failCode    失败代码
     * @param failMessage 失败信息
     */
    public static <T> PageResponse<T> fail(BizConstant failCode, String failMessage) {
        return new PageResponse<>(false, failCode, failMessage);
    }

    public BaseResponse<T> failed(String failCode, String failMessage) {
        return fail(failCode, failMessage);
    }

    /**
     * 构造函数
     *
     * @param message 校验时数据不存在信息
     */
    public static <T> PageResponse<T> invalidate(String message) {
        return new PageResponse<>(false, BizConstant.BIZ_FAILURE, message);
    }

    public PageResponse<T> invalidation(String message) {
        return invalidate(message);
    }


    public long getCount() {
        return count;
    }

    public void setCount(long count) {
        this.count = count;
    }

    public int getPageNo() {
        return pageNo;
    }

    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public List<T> getPageData() {
        return pageData;
    }

    public void setPageData(List<T> pageData) {
        this.pageData = pageData;
    }

    /**
     * 获取开始行
     *
     * @return
     */
    public long getStartRow() {
        startRow = (this.getPageNo() - 1) * this.getPageSize();
        return startRow;
    }

    /**
     * 获取结束行
     *
     * @return
     */
    public long getEndRow() {
        endRow = this.getPageNo() * this.getPageSize();
        return endRow;
    }

    /**
     * 获取最大页数
     *
     * @return
     */
    public long getPageCount() {
        pageCount = this.getCount() / this.getPageSize();
        long rest = this.getCount() % this.getPageSize();
        if (rest > 0) {
            pageCount += 1;
        }
        return pageCount;
    }

    public void setPageCount(int pageCount) {
        this.pageCount = pageCount;
    }


    public BaseResponse<T> toBaseResponse() {
        return new BaseResponse<>(this.isSuccess(), BizConstant.valueOf(this.getCode()), this.getMessage(), this.getCausedBy(), this.getData());
    }
}
